package github.kawaiior.yuanchuxiuzhen.common.world.dimension;

import github.kawaiior.yuanchuxiuzhen.common.block.ore.ManaStoneOre;
import github.kawaiior.yuanchuxiuzhen.core.init.BlockInit;
import net.minecraft.block.material.Material;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.fluid.Fluids;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.common.util.ITeleporter;

import java.util.function.Function;

public class YcxzTeleporter implements ITeleporter {

    public BlockPos thisPos = BlockPos.ZERO;
    public boolean insideDimension = true;

    public YcxzTeleporter(BlockPos pos, boolean insideDim) {
        thisPos = pos;
        insideDimension = insideDim;
    }

    @Override
    public Entity placeEntity(Entity entity, ServerWorld currentWorld, ServerWorld destinationWorld,
                              float yaw, Function<Boolean, Entity> repositionEntity) {
        entity = repositionEntity.apply(false);
        BlockPos pos;

        if (insideDimension) {
            if (entity instanceof ServerPlayerEntity) {
                pos = getSpawnPos((ServerPlayerEntity) entity);
            }
            else {
                pos = thisPos;
            }
        }else {
            pos = new BlockPos(thisPos.getX() / 10F, 0, thisPos.getZ() / 10F);
        }

        int tries = 0;
        while ((destinationWorld.getBlockState(pos).getMaterial() != Material.AIR) &&
                !destinationWorld.getBlockState(pos).isReplaceable(Fluids.WATER) &&
                destinationWorld.getBlockState(pos.up()).getMaterial() != Material.AIR &&
                !destinationWorld.getBlockState(pos.up()).isReplaceable(Fluids.WATER) && tries < 25) {
            pos = pos.up(2);
            tries++;
        }

        entity.setPositionAndUpdate(pos.getX(), pos.getY(), pos.getZ());

//        if (insideDimension) {
//            boolean doSetBlock = true;
//            for (BlockPos checkPos : BlockPos.getAllInBoxMutable(destinationPos.down(10).west(10), destinationPos.up(10).east(10))) {
//                if (destinationWorld.getBlockState(checkPos).getBlock() instanceof ManaStoneOre) {
//                    doSetBlock = false;
//                    break;
//                }
//            }
//            if (doSetBlock) {
//                destinationWorld.setBlockState(destinationPos, BlockInit.MANA_STONE_ORE_BLOCK_9.get().getDefaultState());
//            }
//        }

        return entity;
    }

    private static BlockPos getSpawnPos(ServerPlayerEntity player) {
        ServerWorld world = player.getServerWorld();
        BlockPos spawnPos;

        // If the player has a bed location, use it. Otherwise, use the world's spawn point.
        if (player.getBedPosition().isPresent()) {
            spawnPos = player.getBedPosition().get();
        } else {
            spawnPos = world.getSpawnPoint();
        }

        return spawnPos;
    }
}
